﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using POI.eTransmittal.Enitity;
using System.Data;
using DevExpress.Data.Filtering;
using System.IO;

namespace POI.eTransmittal.BusinessRule
{
    public static class CommonBusinessRules
    {
        public static void GenerateContact(UnitOfWork CurrentUnitOfWork)
        {
            //--->file://///server/share name/path/"Curt_C [MVP]
#if DEBUG
            XPCollection<Contact> contacts = new XPCollection<Contact>(CurrentUnitOfWork);
            if (contacts.Count <= 0)
            {

                Contact ct1 = new Contact(CurrentUnitOfWork);
                ct1.Internal = true;
                ct1.Name = "Radio Room";
                ct1.AddFaxNo("456789");
                //   ct1.FaxNo = "456789";
                ct1.Save();
                CurrentUnitOfWork.CommitChanges();
                ct1 = new Contact(CurrentUnitOfWork);
                ct1.Internal = true;
                ct1.Name = "PONSBV";
                ct1.AddFaxNo("456781");
                // ct1.FaxNo = "N/A";
                ct1.Save();
                CurrentUnitOfWork.CommitChanges();
                ct1 = new Contact(CurrentUnitOfWork);
                ct1.Name = "PT GDI";
                ct1.AddFaxNo("3456789");
                //  ct1.FaxNo = "3456789";
                ct1.Save();
                CurrentUnitOfWork.CommitChanges();
                ct1 = new Contact(CurrentUnitOfWork);
                ct1.Name = "PT XYZ";
                ct1.AddFaxNo("3456779");
                ct1.AddFaxNo("3456778");
                // ct1.FaxNo = "3456779";
                ct1.Save();
                CurrentUnitOfWork.CommitChanges();
                ct1 = new Contact(CurrentUnitOfWork);
                ct1.Name = "PT Zyx";
                //  ct1.FaxNo = "3456771";
                ct1.Save();

                CurrentUnitOfWork.CommitChanges();
            }
#endif
        }



        public static int NewIncomingTransmittal(UnitOfWork CurrentUnitOfWork, string inbox, DateTime receivedDate, string subject, string from,  string attn, string cc, string CurrUserId, string remarks)
        {
            IncomingTransmittal trns = new IncomingTransmittal(CurrentUnitOfWork);
            trns.Attn = attn;
            trns.Cc = cc;
            trns.ReceivedDate = receivedDate;
            trns.InboxName = inbox;
            trns.Subject = subject;

            trns.From = from;
           
            trns.Remarks = remarks;
            trns.CreatedBy = CurrUserId;
            trns.CreatedDate = DateTime.Now;
            trns.Status = IncomingTransmittal.STATUS_DRAFT;
            trns.Save();
            CurrentUnitOfWork.CommitChanges();
            return trns.ID;
        }

        public static void DistributeIncomingTransmittal(UnitOfWork CurrentUnitOfWork, int Log, string fileName, string originalFilename)
        {
            IncomingTransmittal trn = CurrentUnitOfWork.FindObject<IncomingTransmittal>(CriteriaOperator.Parse("ID = ?", Log));
            if (trn != null)
            {

                trn.FaxFileLink = fileName;
                trn.OriginalFileName = originalFilename;
                trn.Save();
                CurrentUnitOfWork.CommitChanges();
                SendEmail(trn);

                trn.Status = IncomingTransmittal.STATUS_DISTRIBUTED;
                trn.Save();
                CurrentUnitOfWork.CommitChanges();
            }
        }

        private static void SendEmail(IncomingTransmittal trn)
        {
            PrepareDefaultSMTPParameter(trn.Session);
            IncomingNotificationSender notifier = new IncomingNotificationSender(trn);
            notifier.testSend();
        }

        private static void PrepareDefaultSMTPParameter(Session session)
        {

        }
        private static DataTable createTableEmployee()
        {
            DataTable tbl = new DataTable();
            tbl.Columns.Add("mail");
            tbl.Columns.Add("Name");
            tbl.AcceptChanges();
            return tbl;
        }
        public static DataTable GetEmployeetable(string url)
        {
            if (url == "test")
            {
                DataTable tbl = createTableEmployee();
                DataRow row = tbl.NewRow();
                row[0] = "automo";
                row[1] = "ari utomo";
                tbl.Rows.Add(row);
                row = tbl.NewRow();
                row[0] = "jamaludin";
                row[1] = "jamaludin";
                tbl.Rows.Add(row);
                row = tbl.NewRow();
                tbl.AcceptChanges();
                return tbl;
            }

            //return new DataTable();
            try
            {
                string[] empdata = ADQuery.QueryEmployeeData(url);
                List<string> data = new List<string>();
                data.AddRange(empdata);
                return ADQuery.GetEmployeeDataTable(data);
            }
            catch (Exception ex)
            {
                DataTable tbl = createTableEmployee();

                return tbl;
            }

        }


        public static string GetIncomingShareFolderToWrite(IncomingTransmittal trns)
        {
            GeneralParameter param = trns.Session.FindObject<GeneralParameter>(CriteriaOperator.Parse("ParamTitle = ?", GeneralParameter.SHARE_FOLDER_LOCATION));
            if (param != null)
            {
                string shareFolder = param.ParamValue;
                string monthYearFolder = trns.CreatedDate.ToString("MMMyyyy");
                string newPath = Path.Combine(shareFolder, monthYearFolder);
                DirectoryInfo di = new DirectoryInfo(newPath);
                if (!di.Exists)
                {
                    di.Create();
                }
                newPath = Path.Combine(newPath, "incoming");
                di = new DirectoryInfo(newPath);
                if (!di.Exists)
                {
                    di.Create();
                }
                return newPath;
            }
            return null;
        }
        public static string GetIncomingShareFolderToWrite(UnitOfWork CurrentUnitOfWork)
        {
            GeneralParameter param = CurrentUnitOfWork.FindObject<GeneralParameter>(CriteriaOperator.Parse("ParamTitle = ?", GeneralParameter.SHARE_FOLDER_LOCATION));
            if (param == null)
            {
                param = new GeneralParameter(CurrentUnitOfWork);
                param.ParamValue = @"C:\Users\adam\Documents\Adam Project\new ETransmittal full web\temp";
                param.ParamTitle = GeneralParameter.SHARE_FOLDER_LOCATION;
                param.ParamDataType = typeof(string).ToString();
                param.ParamDesc = "ShareFolderLocation";
                param.Save();
                CurrentUnitOfWork.CommitChanges();
            }

            string shareFolder = param.ParamValue;
            string monthYearFolder = DateTime.Today.ToString("MMMyyyy");
            string newPath = Path.Combine(shareFolder, monthYearFolder);
            DirectoryInfo di = new DirectoryInfo(newPath);
            if (!di.Exists)
            {
                di.Create();
            }
            newPath = Path.Combine(newPath, "incoming");
            di = new DirectoryInfo(newPath);
            if (!di.Exists)
            {
                di.Create();
            }
            return newPath;
        }



        public static Contact GetContactByName(UnitOfWork CurrentUnitOfWork, string p)
        {
            Contact ct = CurrentUnitOfWork.FindObject<Contact>(CriteriaOperator.Parse("Name = ?", p));
            return ct;
        }

        public static Contact CreateContact(UnitOfWork CurrentUnitOfWork, string p, bool intern)
        {
            Contact ct = new Contact(CurrentUnitOfWork);
            ct.Name = p;
            ct.Internal = intern;
            return ct;
        }

        public static bool ContactNameExist(UnitOfWork CurrentUnitOfWork, string p)
        {
            return CurrentUnitOfWork.FindObject<Contact>(CriteriaOperator.Parse("UPPER(Name) = ?", p.ToUpper())) == null ? false : true;
        }

        public static ContactInfo GetContactInfoByFax(UnitOfWork CurrentUnitOfWork, string p)
        {
            return CurrentUnitOfWork.FindObject<ContactInfo>(CriteriaOperator.Parse("Type = ? and Value = ?", ContactInfo.FAX, p));

        }

        public static string GetIncomingTransmittalFileName(UnitOfWork CurrentUnitOfWork, int LogNo, string ext)
        {
            IncomingTransmittal trns = CurrentUnitOfWork.FindObject<IncomingTransmittal>(CriteriaOperator.Parse("ID = ?", LogNo));
            if (trns != null)
            {
                return trns.GetFileName(ext);
            }
            return null;
        }

        public static string GetGeneralParameterByTitle(string title, Session session)
        {

            GeneralParameter gp = session.FindObject<GeneralParameter>(CriteriaOperator.Parse("ParamTitle=?", title));
            if (gp != null)
                return gp.ParamValue;
            else
            {
                switch (title)
                {
                    case GeneralParameter.FAX_EXPRESSION:
                        gp = new GeneralParameter(session);
                        gp.ParamTitle = title;
                        gp.ParamDataType = typeof(string).ToString();
                        gp.ParamValue = "[FAX:9#fax#]";
                        gp.Save("system");
                        session.CommitTransaction();
                        return gp.ParamValue;
                      

                }
            }
            return null;
        }

        public static IncomingTransmittal GetIncomingTransmittal(UnitOfWork CurrentUnitOfWork, string p)
        {
            return CurrentUnitOfWork.FindObject<IncomingTransmittal>(CriteriaOperator.Parse("ID = ?", p));
        }





        public static void GenerateInbox(UnitOfWork CurrentUnitOfWork)
        {
            XPCollection<Inbox> ibxs = new XPCollection<Inbox>(CurrentUnitOfWork);
            if (ibxs.Count < 1)
            {
                Inbox ibx = new Inbox(CurrentUnitOfWork);
                ibx.Name = "jkt_main";
                ibx.Description = "10th floor radio room.";
                ibx.CreatedBy = "system";
                ibx.CreatedDate = DateTime.Now;
                ibx.Save();
                CurrentUnitOfWork.CommitChanges();
            }

        }

        public static void SaveIncoming(UnitOfWork CurrentUnitOfWork, string log, string inbox, DateTime receivedDate, string subject, string from, string attn, string cc, string CurrUserId, string remarks)
        {
            IncomingTransmittal trns = GetIncomingTransmittal(CurrentUnitOfWork, log);
            if (trns != null)
            {
                trns.Cc = cc;
                trns.ReceivedDate = receivedDate;
                trns.InboxName = inbox;
                trns.Subject = subject;
                trns.Attn = attn;
                trns.Cc = cc;
                trns.From = from;
                
                trns.Remarks = remarks;
                trns.LastChangedBy = CurrUserId;
                trns.LastChangedDate = DateTime.Now;
                trns.Save();
                CurrentUnitOfWork.CommitChanges();

            }
        }

        public static void DistributeIncomingTransmittal(UnitOfWork CurrentUnitOfWork, int Log)
        {
            IncomingTransmittal trn = CurrentUnitOfWork.FindObject<IncomingTransmittal>(CriteriaOperator.Parse("ID = ?", Log));
            if (trn != null)
            {

                checkValidForDistribution(trn);
                SendEmail(trn);

                trn.Status = IncomingTransmittal.STATUS_DISTRIBUTED;
                trn.Save();
                CurrentUnitOfWork.CommitChanges();
            }
            else
            {
                throw new Exception("Incoming Transmittal with log number: " + Log.ToString() + " is not found");
            }
        }

        private static void checkValidForDistribution(IncomingTransmittal trn)
        {
            if (string.IsNullOrEmpty(trn.Attn))
                throw new Exception("Attn field is required for distribution.");

            if (string.IsNullOrEmpty(trn.FaxFileLink))
                throw new Exception("The document that relate to fax, is not provided");
            else
            {
                FileInfo fi = new FileInfo(trn.FaxFileLink);
                if (!fi.Exists)
                    throw new Exception("The document that relate to fax, is not found");
            }
            if (string.IsNullOrEmpty(trn.From))
                throw new Exception("From field is required for distribution.");
            if (string.IsNullOrEmpty(trn.Subject))
                throw new Exception("Subject field is required for distribution.");
            if (trn.ReceivedDate == DateTime.MinValue)
                throw new Exception("ReceivedDate field is required for distribution.");

        }

        public static void SaveIncoming(UnitOfWork CurrentUnitOfWork, string p, string inbox, DateTime receivedDate, string subject, string from, string attn, string cc, string CurrUserId, string remarks, string shareFolder, string fileName)
        {
            SaveIncoming(CurrentUnitOfWork, p, inbox, receivedDate, subject, from,  attn, cc, CurrUserId, remarks);
            IncomingTransmittal trns = GetIncomingTransmittal(CurrentUnitOfWork, p);
            trns.OriginalFileName = fileName;
            trns.FaxFileLink = shareFolder;
            trns.Save();
            CurrentUnitOfWork.CommitChanges();
        }

        public static void PrepareDocTypeDefaultValues(UnitOfWork CurrentUnitOfWork,string userId)
        {
            createDocType(CurrentUnitOfWork, "CORR", "Correspondence", "PO/[code]/[yymm]/sequence", userId);
            createDocType(CurrentUnitOfWork, "INVIT", "Invitation Letter", "PO/[code]/[yymm]/sequence", userId);
        }

        private static void createDocType(UnitOfWork CurrentUnitOfWork, string code, string Typename, string Formula,string userId)
        {
            DocumentType dt = CurrentUnitOfWork.FindObject<DocumentType>(CriteriaOperator.Parse("upper(Code) = ?", code.ToUpper()));
            if (dt == null)
            {
                dt = new DocumentType(CurrentUnitOfWork);
                dt.Code = code;
                dt.CreatedBy = userId;
                dt.TypeName = Typename; ;
                dt.Formula = Formula;
                dt.Save(userId);
                CurrentUnitOfWork.CommitChanges();
            }
        }

        public static OutgoingTransmittal  CreateNewOutGoingTransmittal(UnitOfWork CurrentUnitOfWork, string subject, string author, string to, string attn, string fax, string remarks, string doctype, string CurrUserId)
        {
            OutgoingTransmittal trns = new OutgoingTransmittal(CurrentUnitOfWork);
            trns.Subject = subject;
            trns.To = to;
            trns.Author = author;
            trns.Attn = attn;
            trns.FaxNo = fax;
            trns.Remarks = remarks;
            trns.Status = OutgoingTransmittal.DRAFT;
            trns.Save(CurrUserId);
            CurrentUnitOfWork.CommitChanges();
            DocumentType dct = CurrentUnitOfWork.FindObject<DocumentType>(CriteriaOperator.Parse("Code =?", doctype));
            if (dct != null)
            {
                trns.DocTypeCode = doctype;
                trns.RefNo  = dct.GenerateRefNumber(trns.ID);
                trns.Save();
                CurrentUnitOfWork.CommitChanges();
            }
            return trns;
        }

        public static OutgoingTransmittal GetOutgoingTransmittal(UnitOfWork CurrentUnitOfWork, string id)
        {
            return CurrentUnitOfWork.FindObject<OutgoingTransmittal>(CriteriaOperator.Parse("ID = ?", id));
        }

        public static void ImportLDAP_USER(UnitOfWork CurrentUnitOfWork,string url)
        {
            DataTable tbl = GetEmployeetable(url);
            foreach (DataRow rw in tbl.Rows)
            {
                string id = rw["mail"].ToString();
                TransmittalUser user = GetTransmittalUserById(CurrentUnitOfWork, id);
                if (user == null)
                {
                    user = new TransmittalUser(CurrentUnitOfWork);
                    user.UserID = id;
                    user.Name = rw["Name"].ToString();
                    user.Email = rw["Email"].ToString();
                    user.Save();
                    CurrentUnitOfWork.CommitChanges();
                }
            }
        }

        private static TransmittalUser GetTransmittalUserById(UnitOfWork CurrentUnitOfWork, string id)
        {
            return CurrentUnitOfWork.FindObject<TransmittalUser>(CriteriaOperator.Parse("UserID = ?", id));
        }

        public static void DeleteContact(UnitOfWork CurrentUnitOfWork, string id)
        {
            Contact cnt = GetContactById(CurrentUnitOfWork, id);
            if (cnt != null)
            {
                CurrentUnitOfWork.Delete(cnt.ContactsInfo);
                cnt.Delete();
                CurrentUnitOfWork.CommitChanges();
            }
        }

        public static Contact GetContactById(UnitOfWork CurrentUnitOfWork, object p)
        {
            return CurrentUnitOfWork.FindObject<Contact>(CriteriaOperator.Parse("ID = ?", p));
        }

        public static void CreateContactFaxInfo(UnitOfWork CurrentUnitOfWork, object ContactID,object Value)
        {
            Contact contact = GetContactById(CurrentUnitOfWork, ContactID);
           
         
            if (contact != null)
            {
               
             
                if (Value != null)
                {
                    if (Value.ToString().Trim() == string.Empty)
                        throw new Exception("Fax cannot be empty");
                    ContactInfo ci = CurrentUnitOfWork.FindObject<ContactInfo>(CriteriaOperator.Parse("Value = ?", Value));
                    if (ci == null)
                    {
                        ci = new ContactInfo(CurrentUnitOfWork);
                        ci.Value = Value.ToString();
                        ci.Type = ContactInfo.FAX;
                        ci.Contact = contact;
                        ci.Save();
                        contact.Save();
                        CurrentUnitOfWork.CommitChanges();
                    }
                    else
                        throw new Exception("Fax with number " + Value.ToString() + " is already assigned");
                }
                else
                {
                    throw new Exception("Fax cannot be empty");
                }
              
            }
              
        }

      

        public static string GetOutgoingTransmittalFileName(UnitOfWork CurrentUnitOfWork, string log, string ext)
        {
            OutgoingTransmittal  trns = CurrentUnitOfWork.FindObject<OutgoingTransmittal>(CriteriaOperator.Parse("ID = ?", log));
            if (trns != null)
            {
                return trns.GetFileName(ext);
            }
            return null;
        }

    

        public static string GetOutgoingShareFolderToWrite(UnitOfWork CurrentUnitOfWork, string log)
        {
            OutgoingTransmittal trns = CurrentUnitOfWork.FindObject<OutgoingTransmittal>(CriteriaOperator.Parse("ID =?", log));

            GeneralParameter param = trns.Session.FindObject<GeneralParameter>(CriteriaOperator.Parse("ParamTitle = ?", GeneralParameter.SHARE_FOLDER_LOCATION));
            if (param != null)
            {
                string shareFolder = param.ParamValue;
                string monthYearFolder = trns.CreatedDate.ToString("MMMyyyy");
                string newPath = Path.Combine(shareFolder, monthYearFolder);
                DirectoryInfo di = new DirectoryInfo(newPath);
                if (!di.Exists)
                {
                    di.Create();
                }
                newPath = Path.Combine(newPath, "outgoing");
                di = new DirectoryInfo(newPath);
                if (!di.Exists)
                {
                    di.Create();
                }
                return newPath;
            }
            return null;
        }

        public static void SaveOutgoing(UnitOfWork CurrentUnitOfWork, string log, string subject, string author, string to, string faxNo, string docTypeCode, string attn, string remarks, string userId)
        {
            OutgoingTransmittal trns = GetOutgoingTransmittal(CurrentUnitOfWork, log);
            if (trns != null)
            {
                trns.Subject = subject;
                trns.Author = author;
                trns.To = to;
                trns.FaxNo = faxNo;
                trns.Attn = attn;
                trns.Remarks = remarks;
                  DocumentType dct = CurrentUnitOfWork.FindObject<DocumentType>(CriteriaOperator.Parse("Code =?", docTypeCode));
                if(dct!=null){
                trns.DocTypeCode = docTypeCode;
                trns.RefNo = dct.GenerateRefNumber(Convert.ToInt32(trns.ID));

                }
                trns.Save(userId);
                CurrentUnitOfWork.CommitChanges();
            }
        }

        public static void SaveOutgoing(UnitOfWork CurrentUnitOfWork, string log, string subject, string author, string to, string faxNo, string docTypeCode, string attn, string remarks, string userId, string newFileName, string shareFolder)
        {
            SaveOutgoing(CurrentUnitOfWork, log, subject, author, to, faxNo, docTypeCode, attn, remarks, userId);
            OutgoingTransmittal trns = GetOutgoingTransmittal(CurrentUnitOfWork, log);
            if (trns != null)
            {
                trns.OriginalFileName = newFileName;
                trns.FaxFileLink = shareFolder;
                trns.Save(userId);
                CurrentUnitOfWork.CommitChanges();
            }

        }

        public static void SendFax(UnitOfWork CurrentUnitOfWork, string log)
        {
            OutgoingTransmittal trns = GetOutgoingTransmittal(CurrentUnitOfWork, log);
            if (trns != null)
            {
                int step=0;
                try
                {
                    FaxSender sender = new FaxSender(trns);
                    sender.SendToFax();
                    step = 1;
                    trns.Status = OutgoingTransmittal.SENT;
                    trns.Save("FaxSender");
                       CurrentUnitOfWork.CommitChanges();
                }
                catch (Exception ex)
                {
                    switch (step)
                    {
                        case 0:
                            throw new Exception("Error:Unable to send fax;" + ex.Message);
                        case 1:
                            throw new Exception("Error:Your transmittal is sent successfully, but it cannot marked as sent;" + ex.Message);

                    }
                }
            }
        }

        public static void SubmitToCoordinator(OutgoingTransmittal trns,string redirectUrl)
        {
            OutgoingNotificationSender sender = new OutgoingNotificationSender(trns);
            sender.SendNotification(redirectUrl);
        }

        public static string GetTempShareFolder(UnitOfWork unitOfWork)
        {
            GeneralParameter param = unitOfWork.FindObject<GeneralParameter>(CriteriaOperator.Parse("ParamTitle = ?", GeneralParameter.SHARE_FOLDER_LOCATION));
            if (param != null)
            {
                string shareFolder = param.ParamValue;
                DirectoryInfo di;

                string newPath = Path.Combine(shareFolder, "temp");
                di = new DirectoryInfo(newPath);
                if (!di.Exists)
                {
                    di.Create();
                }
                return newPath;
            }
            return null;
        }

        public static void CheckExtention(UnitOfWork CurrentUnitOfWork, string ext)
        {
            GeneralParameter prm = CurrentUnitOfWork.FindObject<GeneralParameter>(CriteriaOperator.Parse("ParamTitle = ?", GeneralParameter.ALLOWED_EXTENTION ));
            if (prm == null)
            {
                prm = new GeneralParameter(CurrentUnitOfWork);
                prm.ParamTitle = GeneralParameter.ALLOWED_EXTENTION;
                prm.ParamValue = ".msg, .pdf";
                prm.ParamDataType = typeof(string).Name;
                prm.ParamDesc = "File extentions that supported by eTransmittal";
                prm.Save("system");
                CurrentUnitOfWork.CommitChanges();
            }
            string[] exts = prm.ParamValue.ToLower().Split(',');
          
            List<string> allowed = new List<string>();
            foreach (string st in exts)
            {
                allowed.Add(st.Trim().ToLower());
            }
           
            if (allowed.IndexOf(ext.Trim().ToLower()) < 0)
            {
                throw new Exception(ext + " files is not supported");
            }
        }
    }
}
